Skip to content

解決 WSL 2 Docker 檔案權限問題

TLDR

  • 核心問題:WSL 2 環境中,Docker 容器以 root 權限建立的檔案,會導致一般使用者身分的 VS Code 無法讀寫,出現 Permission Denied
  • 暴力解法(不推薦):修改 /etc/wsl.conf 將 WSL 預設使用者改為 root,雖能解決權限問題,但存在極大資安風險。
  • 推薦做法 (Dev Containers):使用 VS Code 的 Dev Containers 功能,將開發環境容器化,並透過 "remoteUser": "root" 設定解決 Bind Mount 的權限衝突。
  • 進階做法 (整合進 Docker Compose):在 compose.yml 中定義一個 vscode-editor 服務,並透過 Dev Containers: Attach to Running Container 連線,將開發環境與專案基礎設施整合。
  • 關鍵提示:使用 docker-outside-of-docker 時,若使用 Bind Mount,路徑解析會指向 Host,建議優先考慮使用 Named Volume 以避開路徑對應問題。

遇到的權限地獄

什麼情況下會遇到這個問題:當你在 WSL 2 中使用 Docker Compose 啟動容器,且容器將檔案掛載(Volume)至本機目錄時。

由於 Docker 容器預設以 root 權限執行,掛載至 WSL 的檔案擁有者會變為 root。當你使用以一般使用者身分執行的 VS Code 嘗試編輯這些檔案時,會因權限不足而失敗。

暴力解法

直接修改 WSL 的設定檔 /etc/wsl.conf,將預設登入使用者改為 root

ini
# /etc/wsl.conf
[user]
default = root

WARNING

這是一個極度不安全的作法。將預設使用者改為 root 會讓你在 WSL 內的所有操作都具有最高權限,一旦誤執行惡意腳本或操作失誤(例如 rm -rf /),後果不堪設想。請勿在生產環境或重要的工作環境中模仿。


解決方案:Dev Containers

什麼情況下會遇到這個問題:當你希望在保持環境一致性的同時,解決跨作業系統的檔案存取權限問題。

Dev Containers 允許將開發環境打包在容器中,並透過自動同步 UID 或指定 remoteUser 來解決權限衝突。

Dev Containers 實戰步驟

  1. 初始化:在 VS Code 中按下 F1,選擇 Dev Containers: Add Dev Container Configuration Files...
  2. 選擇定義:選擇適合的環境(如 Ubuntu),並務必勾選 Docker (outside of Docker) 功能。
  3. 設定 devcontainer.json: 若使用 Bind Mount,必須在設定檔中啟用 remoteUser
    json
    "remoteUser": "root"
  4. 重新開啟:按下 F1 選擇 Dev Containers: Reopen in Container

TIP

devcontainer.json 若有修改,必須執行 Rebuild 才會生效。若錯過重建提示,可透過指令面板重新執行。


進階做法:將 Dev Container 整合進 Docker Compose

什麼情況下會遇到這個問題:當你不希望產生額外的 .devcontainer 資料夾,或希望開發環境與專案服務定義在同一個 compose.yml 中。

你可以新增一個專門用於編輯的容器服務:

設定方式

compose.ymlcompose.override.yml 中加入:

yaml
services:
  vscode-editor:
    image: mcr.microsoft.com/devcontainers/base:ubuntu-24.04
    container_name: vscode-editor
    command: sleep infinity
    user: root
    volumes:
      - ./:/workspace
    working_dir: /workspace

連結步驟

  1. 啟動服務:docker compose up -d
  2. 在 VS Code 中按下 F1,選擇 Dev Containers: Attach to Running Container...
  3. 選擇 vscode-editor 容器。
  4. 開啟容器內的 /workspace 目錄。

TIP

若不希望開發環境設定汙染正式的 compose.yml,建議將上述設定移至 compose.override.yml,Docker Compose 會自動合併設定。


異動歷程

    • 初版文件建立。
    • 補充將 Dev Container 整合進 Docker Compose 的另一種做法。
    • 補充關於使用 compose.override.yml 的建議。